/**
 * @Description: 处理水印图片 指令
 * @Author 卞鹏飞 <228443632@qq.com>
 * @create 2023/7/22 16:21
 * @example
 * <el-image v-water-marker-image/>
 * <img src='xxx' v-water-marker-image/>
 */

/**
 * 处理水印工单
 * @param {string} url 地址
 * @param {'center'|'left'} textAlign 位置 center
 * @param  {'top'|'middle'|'bottom'|'hanging'} textBaseline 设置基线（垂直对齐方式 ）
 * @param {string} font
 * @param {string} fillStyle
 * @param {string} content 文字内容
 * @param {Function} cb
 * @param {'center'|string} position
 */
function pictureWM({
  url = '',
  textAlign = 'center',
  textBaseline = 'middle',
  font = '16px Microsoft Yahei',
  fillStyle = '#F2F3F5',
  content = '特资星',
  cb = null,
  // textX = 100,
  // textY = 30,
  position = ''
} = {}) {
  return new Promise((resolve) => {
    const img = new Image()
    img.crossOrigin = 'anonymous'
    if (/^data:/.test(url)) {
      // base 64
      img.src = url
    } else {
      // 普通地址
      // center
      img.src = url
    }
    img.onload = function () {
      const canvas = document.createElement('canvas')
      canvas.width = img.width
      canvas.height = img.height
      const ctx = canvas.getContext('2d')
      ctx.drawImage(img, 0, 0)
      ctx.textAlign = textAlign
      ctx.textBaseline = textBaseline
      ctx.font = font
      ctx.fillStyle = fillStyle

      if (position == 'center') {
        // 获取输入文本的实际高度
        const getActualHeight = () => {
          const { actualBoundingBoxAscent, actualBoundingBoxDescent } = ctx.measureText(content)
          return actualBoundingBoxAscent + actualBoundingBoxDescent
        }

        // 获取输入文本的实际宽度
        const getActualWidth = () => {
          const { actualBoundingBoxLeft, actualBoundingBoxRight } = ctx.measureText(content)
          return actualBoundingBoxLeft + actualBoundingBoxRight
        }

        // 绘制文本
        ctx.fillText(
          content,
          (img.width - getActualWidth()) / 2 + ctx.measureText(content).actualBoundingBoxLeft, // 修正部分字体不由水平中线(center)均分导致的位移
          (img.height - getActualHeight()) / 2 + ctx.measureText(content).actualBoundingBoxAscent // 修正部分字体不由垂直中线(middle)均分导致的位移
        )
      } else {
        let height = 80 // 两个水印之间的垂直高度
        let width = 70 // 两个水印之间的水平高度
        let fontSize = 14 // 水印字体大小
        ctx.rotate((-20 * Math.PI) / 180)
        ctx.font = font || '16px Microsoft JhengHei'
        // ctx.textBaseline = textBaseline || 'middle'
        // ctx.rotate(17 * Math.PI / 180) // 文本旋转角度设置
        let i = 0,
          j = 0,
          waterMarkerWidth = content.split('').length * fontSize
        for (i = 0; i < canvas.width / waterMarkerWidth; i++) {
          for (j = 0; j < canvas.height / (height - 20); j++) {
            if (j == 0) {
              ctx.fillText(content, i * (waterMarkerWidth + width), -height, canvas.width)
            }
            ctx.fillText(content, i * (waterMarkerWidth + width), j * height, canvas.width)
          }
        }
        // ctx.fillText(content, canvas.width / 10, canvas.height / 2)
      }
      const base64Url = canvas.toDataURL()
      cb && cb(base64Url)
      resolve(base64Url)
    }
  })
}

/**
 * 更新图片水印
 * @param {HTMLElement} img
 * @param {object} value
 * @return {Promise<void>}
 */
const updatePicVM = async ({ img = null, value = {} }) => {
  value.url ||= img?.src
  const vmOriginSrc = img?.dataset?.vmOriginSrc
  console.log('vmOriginSrc', vmOriginSrc, value.url, img)
  if (value.url && value.url != vmOriginSrc) {
    const base64URL = await pictureWM(value)
    console.log('base64URL', base64URL)
    img.dataset.vmOriginSrc = value.url
    img.src = base64URL
  }
}

export default {
  /**
   * 初始化
   * @param el
   * @param binding
   * @return {Promise<void>}
   */
  async mounted(el, binding) {
    if (el.nodeType != 1) return
    const value = binding.value || {}
    el.__mutationOb__ = new MutationObserver(() => {
      const imgDOMList = [...el.querySelectorAll('img')]
      if (el?.tagName === 'IMG') imgDOMList.unshift(el)
      imgDOMList.forEach((imgItem) => {
        updatePicVM({ img: imgItem, value })
      })
    })
    el.__mutationOb__.observe(el, { attributes: true, childList: true, subtree: true })
  },

  /**
   * 更新
   * @param el
   * @param binding
   * @return {Promise<void>}
   */
  async update(el, binding) {
    const value = binding.value || {}
    const imgDOMList = el.querySelectorAll('img')
    if (el?.tagName === 'IMG') imgDOMList.unshift(el)
    imgDOMList.forEach((imgItem) => {
      updatePicVM({ img: imgItem, value })
    })
  },

  /**
   * 卸载
   * @param el
   */
  beforeUnmount(el) {
    el.__mutationOb__.disconnect()
    el.__mutationOb__ = null
  }
}
